package com.china08.yxyapi.service.res.mistakes.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.china08.yxyapi.entity.db.res.YxyResResource;
import com.china08.yxyapi.entity.es.ElasticYxyResResource;
import com.china08.yxyapi.repository.db.YxyResResourceRepository;
import com.china08.yxyapi.repository.db.YxyResWeikeKnowRepository;
import com.china08.yxyapi.service.res.mistakes.MistakesWeikeService;
import com.china08.yxyapi.service.yxyresource.impl.YxyResourceServiceImpl;

@Service
public class MistakesWeikeServiceImpl implements MistakesWeikeService {

    @Autowired
    private YxyResourceServiceImpl yxyResourceServiceImpl;

    @Autowired
    YxyResWeikeKnowRepository yxyResWeikeKnowRepository;

    @Autowired
    YxyResResourceRepository yxyResResourceRepository;

    // 教师端
    @Override
    public List<YxyResResource> getMistakesWeiKeForTeacher(String tecId, String schId, List<Integer> knowLst) {
        List<String> idLst = new ArrayList<String>();

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        // 刨除已删除的
        TermQueryBuilder builderDel = new TermQueryBuilder("isDelete", 0);
        boolQueryBuilder.must(builderDel);

        // 刨除是私有的
        int[] arr = { 1, 2 };
        TermsQueryBuilder builderViewScop = new TermsQueryBuilder("viewScope", arr);
        boolQueryBuilder.must(builderViewScop);

        // 只查询审核已通过的
        TermQueryBuilder builderStatusYes1 = new TermQueryBuilder("status", 1);
        boolQueryBuilder.must(builderStatusYes1);

        // 只查询上传者ID的
        // TermQueryBuilder builderUploaderId = new
        // TermQueryBuilder("uploaderId", tecId);
        // boolQueryBuilder.must(builderUploaderId);

        // 根据知识点查询(集合)
        BoolQueryBuilder knoBuilder = new BoolQueryBuilder();
        TermsQueryBuilder builderknowOne = new TermsQueryBuilder("knowIds", knowLst);

        knoBuilder.must(builderknowOne);
        // knoBuilder.should(builderknowTwo);
        // knoBuilder.should(builderknowThree);
        boolQueryBuilder.must(knoBuilder);

        List<YxyResResource> yrrLst = new ArrayList<>();

        List<ElasticYxyResResource> list = yxyResourceServiceImpl.getAll(boolQueryBuilder);

        // 平台微课数据 根据为云校上传&上传到教育云
        List<ElasticYxyResResource> pingtai = list.stream()
                .filter(x -> x.getIsYxYunRes() == 1 && x.getViewScope() == 2 && x.getIsYxView() == 1)
                .collect(Collectors.toList());

        // 教师微课数据 根据上传人&上传到学校
        List<ElasticYxyResResource> jiaoshi = list.stream()
                .filter(x -> tecId.equals(x.getUploaderId()) && x.getViewScope() == 1 && x.getIsYxView() == 0)
                .collect(Collectors.toList());

        // 学校微课数据 根据上传学校&上传人不为当前老师&上传到学校
        List<ElasticYxyResResource> xuexiao = list.stream().filter(x -> schId.equals(x.getUploaderSchoolId())
                && !tecId.equals(x.getUploaderId()) && x.getViewScope() == 1 && x.getIsYxView() == 0)
                .collect(Collectors.toList());

        // 其他微课数据 根据不为云校上传&上传到教育云
        List<ElasticYxyResResource> qita = list.stream()
                .filter(x -> x.getIsYxYunRes() != 1 && x.getViewScope() == 2 && x.getIsYxView() == 0)
                .collect(Collectors.toList());

        pingtai.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getPv().compareTo(h1.getPv()));
        jiaoshi.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getCreatedDate()
                .compareTo(h1.getCreatedDate()));
        xuexiao.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getPv().compareTo(h1.getPv()));
        qita.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getPv().compareTo(h1.getPv()));

        // 平台微课数据
        for (ElasticYxyResResource elasticYxyResResource : pingtai) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        // 出题人教师上传微课数据(最多三条)
        int jsc = 0;
        for (int i = 0; i < jiaoshi.size(); i++) {
            idLst.add(jiaoshi.get(i).getId());
            YxyResResource resource = yxyResResourceRepository.findById(jiaoshi.get(i).getId());
            if (resource != null) {
                yrrLst.add(resource);
                jsc++;
                if (jsc == 3) {
                    break;
                }
            }
        }

        // 本校教师上传微课数据
        for (ElasticYxyResResource elasticYxyResResource : xuexiao) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        // 其他教师上传微课数据
        for (ElasticYxyResResource elasticYxyResResource : qita) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        yrrLst.stream().filter(distinctByKey(p -> p.getId())).forEach(p -> System.out.println(p.getId()));
        return yrrLst;
    }

    /**
     * 错题本
     */
    @Override
    public List<YxyResResource> getMistakesWeiKeForStudent(List<String> tecId, String schId, List<Integer> knowLst) {
        List<String> idLst = new ArrayList<String>();

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        // 刨除已删除的
        TermQueryBuilder builderDel = new TermQueryBuilder("isDelete", 0);
        boolQueryBuilder.must(builderDel);

        // 刨除是私有的
        int[] arr = { 1, 2 };
        TermsQueryBuilder builderViewScop = new TermsQueryBuilder("viewScope", arr);
        boolQueryBuilder.must(builderViewScop);

        // 只查询审核已通过的
        TermQueryBuilder builderStatusYes1 = new TermQueryBuilder("status", 1);
        boolQueryBuilder.must(builderStatusYes1);

        // 只查询上传者ID的(集合)
        // BoolQueryBuilder uploadBuilder = new BoolQueryBuilder();
        // TermsQueryBuilder builderUploaderId = new
        // TermsQueryBuilder("uploaderId", tecId);
        // uploadBuilder.should(builderUploaderId);
        // boolQueryBuilder.must(uploadBuilder);

        // 根据知识点查询(集合)
        BoolQueryBuilder knoBuilder = new BoolQueryBuilder();
        TermsQueryBuilder builderknowOne = new TermsQueryBuilder("knowIds", knowLst);

        knoBuilder.must(builderknowOne);
        // knoBuilder.should(builderknowTwo);
        // knoBuilder.should(builderknowThree);
        boolQueryBuilder.must(knoBuilder);

        List<YxyResResource> yrrLst = new ArrayList<>();

        List<ElasticYxyResResource> list = yxyResourceServiceImpl.getAll(boolQueryBuilder);

        // 平台微课数据 根据为云校上传&上传到教育云
        List<ElasticYxyResResource> pingtai = list.stream().filter(x -> x.getIsYxYunRes() == 1 && x.getViewScope() == 2)
                .collect(Collectors.toList());

        // 教师微课数据 根据上传人&上传到学校
        List<ElasticYxyResResource> jiaoshi = list.stream()
                .filter(x -> tecId.contains(x.getUploaderId()) && x.getViewScope() == 1).collect(Collectors.toList());

        // 学校微课数据 根据上传学校&上传人不为当前老师&上传到学校
        List<ElasticYxyResResource> xuexiao = list.stream().filter(x -> schId.equals(x.getUploaderSchoolId())
                && !tecId.contains(x.getUploaderId()) && x.getViewScope() == 1).collect(Collectors.toList());

        // 其他微课数据 根据不为云校上传&上传到教育云
        List<ElasticYxyResResource> qita = list.stream().filter(x -> x.getIsYxYunRes() != 1 && x.getViewScope() == 2)
                .collect(Collectors.toList());

        pingtai.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getPv().compareTo(h1.getPv()));
        jiaoshi.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getCreatedDate()
                .compareTo(h1.getCreatedDate()));
        xuexiao.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getPv().compareTo(h1.getPv()));
        qita.sort((ElasticYxyResResource h1, ElasticYxyResResource h2) -> h2.getPv().compareTo(h1.getPv()));

        // 平台微课数据
        for (ElasticYxyResResource elasticYxyResResource : pingtai) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        // 出题人教师上传微课数据(最多三条)
        for (ElasticYxyResResource elasticYxyResResource : jiaoshi) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        // 本校教师上传微课数据
        for (ElasticYxyResResource elasticYxyResResource : xuexiao) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        // 其他教师上传微课数据
        for (ElasticYxyResResource elasticYxyResResource : qita) {
            idLst.add(elasticYxyResResource.getId());
            YxyResResource resource = yxyResResourceRepository.findById(elasticYxyResResource.getId());
            if (resource != null) {
                yrrLst.add(resource);
            }
        }

        yrrLst.stream().filter(distinctByKey(p -> p.getId())).forEach(p -> System.out.println(p.getId()));
        return yrrLst;
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}
